package xcmg.device.service.ratingManager;

import com.github.pagehelper.PageInfo;
import yb.ecp.fast.infra.util.PageHelperPlus;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xcmg.device.dao.entity.company.CompanyDealerDO;
import xcmg.device.dao.entity.ratingManager.AccountOverdueConfigDO;
import xcmg.device.dao.entity.ratingManager.CompleteRateConfigDO;
import xcmg.device.dao.entity.ratingManager.InventoryBusinessConfigDO;
import xcmg.device.dao.entity.ratingManager.MarketDealerRatingDO;
import xcmg.device.dao.entity.ratingManager.MarketDealerRatingDetailDO;
import xcmg.device.dao.entity.ratingManager.MonthPlanAccuracyDetailDO;
import xcmg.device.dao.entity.ratingManager.OrderNormativeDetailDO;
import xcmg.device.dao.entity.ratingManager.OverallCompleteDetailDO;
import xcmg.device.dao.entity.ratingManager.RatingConfigTimeDO;
import xcmg.device.dao.entity.ratingManager.RatingInfoDO;
import xcmg.device.dao.entity.ratingManager.ReceivableOverdueDetailDO;
import xcmg.device.dao.entity.ratingManager.SalesCompleteConfigDO;
import xcmg.device.dao.entity.ratingManager.SalesCompleteDetailDO;
import xcmg.device.dao.entity.ratingManager.ScoreInfoDO;
import xcmg.device.dao.entity.ratingManager.StockBusinessDetailDO;
import xcmg.device.dao.mapper.CompanyDealerMapper;
import xcmg.device.dao.mapper.ratingManager.AccountOverdueConfigDOMapper;
import xcmg.device.dao.mapper.ratingManager.CompleteRateConfigDOMapper;
import xcmg.device.dao.mapper.ratingManager.InventoryBusinessConfigDOMapper;
import xcmg.device.dao.mapper.ratingManager.MarketDealerRatingDetailMapper;
import xcmg.device.dao.mapper.ratingManager.MarketDealerRatingMapper;
import xcmg.device.dao.mapper.ratingManager.MonthPlanAccuracyDetailDOMapper;
import xcmg.device.dao.mapper.ratingManager.OrderNormativeDetailDOMapper;
import xcmg.device.dao.mapper.ratingManager.OverallCompleteDetailDOMapper;
import xcmg.device.dao.mapper.ratingManager.RatingConfigTimeDOMapper;
import xcmg.device.dao.mapper.ratingManager.RatingInfoDOMapper;
import xcmg.device.dao.mapper.ratingManager.ReceivableOverdueDetailMapper;
import xcmg.device.dao.mapper.ratingManager.RuleStrategyRelationDOMapper;
import xcmg.device.dao.mapper.ratingManager.SalesCompleteConfigDOMapper;
import xcmg.device.dao.mapper.ratingManager.SalesCompleteDetailDOMapper;
import xcmg.device.dao.mapper.ratingManager.ScoreInfoDOMapper;
import xcmg.device.dao.mapper.ratingManager.StockBusinessDetailDOMapper;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.ExportUtil;
import xcmg.device.infra.enums.RatingConfigTimeEnum;
import xcmg.device.infra.enums.SalesCompleteDetailEnum;
import xcmg.device.service.vo.FunctionResult;
import xcmg.device.service.vo.marketing.MarketingActivityVO;
import xcmg.device.service.vo.ratingManager.BasisQueryVO;
import xcmg.device.service.vo.ratingManager.ScoreInfoVO;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by wrg on 2019/7/11.
 */
@Service
public class ScoreInfoService {
    @Autowired
    private SalesCompleteConfigDOMapper salesCompleteConfigDOMapper;
    @Autowired
    private ScoreInfoDOMapper scoreInfoDOMapper;
    @Autowired
    private FastGenClient genClient;
    @Autowired
    private SalesCompleteDetailDOMapper salesCompleteDetailDOMapper;
    @Autowired
    private RatingConfigTimeDOMapper ratingConfigTimeDOMapper;
    @Autowired
    private MonthPlanAccuracyDetailDOMapper monthPlanAccuracyDetailDOMapper;
    @Autowired
    private OrderNormativeDetailDOMapper orderNormativeDetailDOMapper;
    @Autowired
    private OverallCompleteDetailDOMapper overallCompleteDetailDOMapper;
    @Autowired
    private ReceivableOverdueDetailMapper receivableOverdueDetailMapper;
    @Autowired
    private AccountOverdueConfigDOMapper accountOverdueConfigDOMapper;
    @Autowired
    private CompleteRateConfigDOMapper completeRateConfigDOMapper;
    @Autowired
    private InventoryBusinessConfigDOMapper inventoryBusinessConfigDOMapper;
    @Autowired
    private StockBusinessDetailDOMapper stockBusinessDetailDOMapper;
    @Autowired
    private HttpServletResponse response;
    @Autowired
    private RatingInfoDOMapper ratingInfoDOMapper;
    @Autowired
    private MarketDealerRatingMapper marketDealerRatingMapper;
    @Autowired
    private MarketDealerRatingDetailMapper marketDealerRatingDetailMapper;
    @Autowired
    private RuleStrategyRelationDOMapper ruleStrategyRelationDOMapper;
    @Autowired
    private CompanyDealerMapper companyDealerMapper;

    @Transactional(rollbackFor = Exception.class)
    public FunctionResult<String> generateRating(String ratingId, String userId, String userName, String orgId) throws Exception {
        FunctionResult<String> functionResult =  new FunctionResult<>();
        List<String> errorInfoList = new ArrayList<>();
        //获取所有客户维护客户的信息
        List<ScoreInfoDO> configClient = scoreInfoDOMapper.getConfigClient(ratingId);
        List<ScoreInfoDO> recordList = new ArrayList<>();
        Date createTime = new Date();
        for (ScoreInfoDO tempScoreInfoDO : configClient) {
            String id = genClient.newGuidText().getValue();
            if (StringUtils.isBlank(id)) {
                functionResult.setCode(ErrorCode.NumberGenerationFailed);
                return functionResult;
            }
            ScoreInfoDO scoreInfoDO = new ScoreInfoDO();
            scoreInfoDO.setId(id);
            scoreInfoDO.setRatingId(ratingId);
            scoreInfoDO.setClientId(tempScoreInfoDO.getClientId());
            scoreInfoDO.setClientName(tempScoreInfoDO.getClientName());
            scoreInfoDO.setCreateTime(createTime);
            scoreInfoDO.setCreatorId(userId);
            scoreInfoDO.setCreatorName(userName);
            recordList.add(scoreInfoDO);
        }
        if (recordList.isEmpty()) {
            functionResult.setCode(ErrorCode.NoRules);
            return functionResult;
        }

        scoreInfoDOMapper.deleteByRatingId(ratingId);
        scoreInfoDOMapper.batchInsert(recordList);
        //获取销售完成配置得分
        getCompleteConfigScore(ratingId, userId, userName, orgId, recordList, createTime,errorInfoList);
        //新增获取月度计划准确性得分
        addMonthAccuracyDetailDOList(ratingId, userId, userName, orgId, recordList, createTime,errorInfoList);
        //新增获取订单管理规范性得分
        addOrderNormativeDetail(ratingId, userId, userName, orgId, recordList, createTime,errorInfoList);
        //新增逾期应收账款逾期
        addReceivableOverdueDetail(ratingId, userId, userName, recordList, createTime,errorInfoList);
        //新增总体销售完成率
        addOverallCompleteDetail(ratingId, userId, userName, orgId, recordList, createTime,errorInfoList);
        //新增库存管理及业务规范性加减分
        addStockBusinessDetail(ratingId, userId, userName, recordList, createTime,errorInfoList);
        //更新各种得分
        batchUpdateScoreInfo(recordList);
        //更新评分主表状态
        RatingInfoDO record = new RatingInfoDO();
        record.setId(ratingId);
        record.setIsScore(1);
        ratingInfoDOMapper.updateByPrimaryKeySelective(record);

        functionResult.setCode(ErrorCode.Success);
        functionResult.setValue(errorInfoList.stream().collect(Collectors.joining(",")));
        return functionResult;
    }

    private void batchUpdateScoreInfo(List<ScoreInfoDO> recordList) {
        for (ScoreInfoDO scoreInfoDO : recordList) {
            Integer accountsOverdue = scoreInfoDO.getAccountsOverdue() == null ? 0 : scoreInfoDO.getAccountsOverdue();
            Integer inventoryBusiness = scoreInfoDO.getInventoryBusiness() == null ? 0 : scoreInfoDO.getInventoryBusiness();
            Integer monthPlanAccuracy = scoreInfoDO.getMonthPlanAccuracy() == null ? 0 : scoreInfoDO.getMonthPlanAccuracy();
            Integer orderManagerNormative = scoreInfoDO.getOrderManagerNormative() == null ? 0 : scoreInfoDO.getOrderManagerNormative();
            Integer salesCompletion = scoreInfoDO.getSalesCompletion() == null ? 0 : scoreInfoDO.getSalesCompletion();
            Integer salesCompletionRate = scoreInfoDO.getSalesCompletionRate() == null ? 0 : scoreInfoDO.getSalesCompletionRate();
            int totalScore = accountsOverdue + inventoryBusiness + monthPlanAccuracy + orderManagerNormative + salesCompletion + salesCompletionRate;
            scoreInfoDO.setTotalScore(totalScore);
        }
        scoreInfoDOMapper.batchUpdate(recordList);
    }

    private void addStockBusinessDetail(String ratingId, String userId, String userName, List<ScoreInfoDO> recordList,
                                        Date createTime,List<String> errorInfo) {
        BasisQueryVO baiscQueryVO = new BasisQueryVO();
        baiscQueryVO.setRatingId(ratingId);
        List<InventoryBusinessConfigDO> businessConfigDOList = inventoryBusinessConfigDOMapper.selectByRatingId(baiscQueryVO);
        if (businessConfigDOList.isEmpty()){
            errorInfo.add("库存管理及业务规范性加减分未设定");
            return;
        }
        List<StockBusinessDetailDO> stockBusinessDetailList = new ArrayList<>();
        for (ScoreInfoDO scoreInfoDO : recordList) {
            StockBusinessDetailDO stockBusinessDetailDO = new StockBusinessDetailDO();
            stockBusinessDetailDO.setCreateTime(createTime);
            stockBusinessDetailDO.setCreatorId(userId);
            stockBusinessDetailDO.setCreatorName(userName);
            stockBusinessDetailDO.setScoreInfoId(scoreInfoDO.getId());
            stockBusinessDetailDO.setId(genClient.newGuidText().getValue());
            String clientId = scoreInfoDO.getClientId();
            for (InventoryBusinessConfigDO inventoryBusinessConfigDO : businessConfigDOList) {
                String clientId1 = inventoryBusinessConfigDO.getClientId();
                if (clientId.equals(clientId1)) {
                    stockBusinessDetailDO.setRemark(inventoryBusinessConfigDO.getRemark());
                    stockBusinessDetailDO.setStockScore(inventoryBusinessConfigDO.getInaccurateDeduction());
                    stockBusinessDetailDO.setCriterionScore(inventoryBusinessConfigDO.getBusinessScore());
                    stockBusinessDetailDO.setScore(inventoryBusinessConfigDO.getBusinessScore() + inventoryBusinessConfigDO.getInaccurateDeduction());
                    break;
                }
            }
            stockBusinessDetailList.add(stockBusinessDetailDO);
            scoreInfoDO.setInventoryBusiness(stockBusinessDetailDO.getScore());
        }

        if (!stockBusinessDetailList.isEmpty()){
            stockBusinessDetailDOMapper.batchInsert(stockBusinessDetailList);
        }
    }

    private void addOverallCompleteDetail(String ratingId, String userId, String userName, String orgId, List<ScoreInfoDO> recordList,
                                          Date createTime,List<String> errorInfo) throws Exception {
        BasisQueryVO baiscQueryVO = new BasisQueryVO();
        baiscQueryVO.setRatingId(ratingId);
        List<CompleteRateConfigDO> completeRateConfigDOList = completeRateConfigDOMapper.selectByRatingId(baiscQueryVO);
        if (completeRateConfigDOList.isEmpty()) {
            errorInfo.add("总体销售完成率配置客户信息未设定");
            return;
        }
        List<Long> completeConfigClient = new ArrayList<>();
        completeRateConfigDOList.forEach(x -> completeConfigClient.add(Long.valueOf(x.getClientId())));
        //获取所有代理商实际销售金额
        RatingConfigTimeDO ratingConfigTimeDO = ratingConfigTimeDOMapper.selectByRatingIdType(ratingId, RatingConfigTimeEnum.OverallSalesCompletionRateConfig.getCode());
        if (null == ratingConfigTimeDO) {
            errorInfo.add("总体销售完成率配置时间未设定");
            return;
        }

        List<SalesCompleteDetailDO> clientSalesAmount = salesCompleteDetailDOMapper.getClientSalesAmount(completeConfigClient
                , orgId, ratingConfigTimeDO.getStartTime(), ratingConfigTimeDO.getEndTime());
        List<OverallCompleteDetailDO> overallCompleteDetailList = new ArrayList<>();
        for (ScoreInfoDO scoreInfoDO : recordList) {
            OverallCompleteDetailDO record = new OverallCompleteDetailDO();
            record.setActualAmount(BigDecimal.ZERO);
            record.setTargetAmount(BigDecimal.ZERO);
            String clientId = scoreInfoDO.getClientId();
            for (SalesCompleteDetailDO salesCompleteDetailDO : clientSalesAmount) {
                String clientId1 = salesCompleteDetailDO.getClientId();
                if (clientId.equals(clientId1)) {
                    BigDecimal temp = salesCompleteDetailDO.getActualSalesAmount() == null ? BigDecimal.ZERO : salesCompleteDetailDO.getActualSalesAmount();
                    record.setActualAmount(temp.add(record.getActualAmount()));
                }
            }

            for (CompleteRateConfigDO completeRateConfigDO : completeRateConfigDOList) {
                String clientId1 = completeRateConfigDO.getClientId();
                if (clientId.equals(clientId1)) {
                    record.setTargetAmount(completeRateConfigDO.getTotalSalesTarget());
                    break;
                }
            }
            record.setCreateTime(createTime);
            record.setCreatorId(userId);
            record.setCreatorName(userName);
            record.setId(genClient.newGuidText().getValue());
            BigDecimal completeRate = BigDecimal.ZERO;
            if (record.getTargetAmount().compareTo(BigDecimal.ZERO) != 0) {
                completeRate = (record.getActualAmount().divide(record.getTargetAmount(), 4, BigDecimal.ROUND_HALF_DOWN))
                        .multiply(new BigDecimal(100)).setScale(2,BigDecimal.ROUND_HALF_DOWN);
            }

            record.setCompleteRate(completeRate + "%");

            setOverallCompleteDetailScore(record, completeRate);

            record.setScoreInfoId(scoreInfoDO.getId());
            scoreInfoDO.setSalesCompletionRate(record.getScore());
            overallCompleteDetailList.add(record);
        }

        if (!overallCompleteDetailList.isEmpty()){
            overallCompleteDetailDOMapper.batchInsert(overallCompleteDetailList);
        }
    }

    private void setOverallCompleteDetailScore(OverallCompleteDetailDO record, BigDecimal completeRate) {
        record.setScore(0);
        if (completeRate.compareTo(new BigDecimal(140)) > 0) {
            record.setScore(10);
            return;
        }
        for (int i = 0; i < 3; i++) {
            if (completeRate.compareTo(new BigDecimal(140 - i * 10)) <= 0 && completeRate.compareTo(new BigDecimal(130 - i * 10)) > 0) {
                record.setScore(8 - i * 2);
                break;
            }
        }
    }

    private void addReceivableOverdueDetail(String ratingId, String userId, String userName, List<ScoreInfoDO> recordList,
                                            Date createTime,List<String> errorInfo) {
        BasisQueryVO baiscQueryVO = new BasisQueryVO();
        baiscQueryVO.setRatingId(ratingId);
        List<AccountOverdueConfigDO> overdueConfigDOList = accountOverdueConfigDOMapper.selectByRatingId(baiscQueryVO);
        if (overdueConfigDOList.isEmpty()) {
            errorInfo.add("应收逾期配置未设定");
            return;
        }
        List<ReceivableOverdueDetailDO> overdueDetailList = new ArrayList<>();
        for (ScoreInfoDO scoreInfoDO : recordList) {
            String clientId = scoreInfoDO.getClientId();
            ReceivableOverdueDetailDO record = null;
            for (AccountOverdueConfigDO accountOverdueConfigDO : overdueConfigDOList) {
                String clientId1 = accountOverdueConfigDO.getClientId();
                if (clientId.equals(clientId1)) {
                    record = new ReceivableOverdueDetailDO();
                    BeanUtils.copyProperties(accountOverdueConfigDO,record);
                    record.setCreateTime(createTime);
                    record.setCreatorId(userId);
                    record.setCreatorName(userName);
                    record.setId(genClient.newGuidText().getValue());
                    record.setScore(accountOverdueConfigDO.getScore().intValue());
                    record.setScoreInfoId(scoreInfoDO.getId());
                    break;
                }
            }
            if (record != null) {
                scoreInfoDO.setAccountsOverdue(record.getScore());
                overdueDetailList.add(record);
            }
        }
        if (!overdueDetailList.isEmpty()) {
            receivableOverdueDetailMapper.batchInsert(overdueDetailList);
        }
    }

    private void addOrderNormativeDetail(String ratingId, String userId, String userName, String orgId, List<ScoreInfoDO> recordList,
                                         Date createTime,List<String> errorInfo) throws Exception {
        RatingConfigTimeDO ratingConfigTimeDO = ratingConfigTimeDOMapper.selectByRatingIdType(ratingId, RatingConfigTimeEnum.OrderManagementNormativeConfig.getCode());
        if (null == ratingConfigTimeDO) {
            errorInfo.add("订单管理规范性配置未设定");
            return;
        }

        List<OrderNormativeDetailDO> orderNormativeDetailDOList = new ArrayList<>();
        for (ScoreInfoDO scoreInfoDO : recordList) {
            OrderNormativeDetailDO record = new OrderNormativeDetailDO();
            Integer urgentOrderCount = monthPlanAccuracyDetailDOMapper.getUrgentOrderCount(orgId, scoreInfoDO.getClientId(),
                    ratingConfigTimeDO.getStartTime(), ratingConfigTimeDO.getEndTime());
            record.setCreateTime(createTime);
            record.setCreatorId(userId);
            record.setCreatorName(userName);
            record.setId(genClient.newGuidText().getValue());
            record.setUrgentOrder(urgentOrderCount == null ? 0 : urgentOrderCount.longValue());
            record.setScoreInfoId(scoreInfoDO.getId());
            record.setAssessmentCriteria(ratingConfigTimeDO.getUrgentOrderMaxQty().longValue());
            long beyondQty = record.getUrgentOrder() - record.getAssessmentCriteria();
            if (beyondQty <= 0) {
                record.setScore(10);
            } else {
                record.setScore((int) (10 - (beyondQty * 2)));
            }

            if (record.getScore() < 0) {
                record.setScore(0);
            }
            orderNormativeDetailDOList.add(record);
            scoreInfoDO.setOrderManagerNormative(record.getScore());
        }
        orderNormativeDetailDOMapper.batchInsert(orderNormativeDetailDOList);
    }

    private void addMonthAccuracyDetailDOList(String ratingId, String userId, String userName, String orgId, List<ScoreInfoDO> recordList,
                                              Date createTime,List<String> errorInfo) throws Exception {
        RatingConfigTimeDO ratingConfigTimeDO = ratingConfigTimeDOMapper.selectByRatingIdType(ratingId, RatingConfigTimeEnum.MonthPlanAccuracyConfig.getCode());
        if (null == ratingConfigTimeDO) {
            errorInfo.add("月度计划准确性配置未设定");
            return;
        }

        List<MonthPlanAccuracyDetailDO> accuracyDetailDOList = new ArrayList<>();
        for (ScoreInfoDO scoreInfoDO : recordList) {
            MonthPlanAccuracyDetailDO record = new MonthPlanAccuracyDetailDO();
            Integer urgentOrderCount = monthPlanAccuracyDetailDOMapper.getUrgentOrderLineCount(orgId, scoreInfoDO.getClientId(),
                    ratingConfigTimeDO.getStartTime(), ratingConfigTimeDO.getEndTime());
            Integer monthOrderCount = monthPlanAccuracyDetailDOMapper.getMonthOrderLineCount(orgId, scoreInfoDO.getClientId(),
                    ratingConfigTimeDO.getStartTime(), ratingConfigTimeDO.getEndTime());
            record.setCreateTime(createTime);
            record.setCreatorId(userId);
            record.setCreatorName(userName);
            record.setId(genClient.newGuidText().getValue());
            record.setMonthOrder(monthOrderCount == null ? 0 : monthOrderCount.longValue());
            record.setUrgentOrder(urgentOrderCount == null ? 0 : urgentOrderCount.longValue());
            record.setScoreInfoId(scoreInfoDO.getId());
            BigDecimal monthOrder = new BigDecimal(record.getMonthOrder());
            BigDecimal urgentOrder = new BigDecimal(record.getUrgentOrder());
            BigDecimal totalOrder = monthOrder.add(urgentOrder);
            BigDecimal accuracyRate;
            if (totalOrder.compareTo(BigDecimal.ZERO) == 0){
                accuracyRate = BigDecimal.ZERO;
            }else {
                accuracyRate = monthOrder.divide(monthOrder.add(urgentOrder),4,BigDecimal.ROUND_HALF_DOWN).
                        multiply(new BigDecimal(100)).setScale(2,BigDecimal.ROUND_HALF_DOWN);
            }
            record.setAccuracyRate(accuracyRate + "%");
            //计算得分
            setMonthPlanAccuracyDetailScore(accuracyRate, record);
            accuracyDetailDOList.add(record);
            scoreInfoDO.setMonthPlanAccuracy(record.getScore());
        }
        monthPlanAccuracyDetailDOMapper.batchInsert(accuracyDetailDOList);
    }

    private void setMonthPlanAccuracyDetailScore(BigDecimal accuracyRate, MonthPlanAccuracyDetailDO record) {
        if (accuracyRate.compareTo(new BigDecimal(80)) > 0) {
            record.setScore(10);
            return;
        }
        if (accuracyRate.compareTo(new BigDecimal(70)) <= 0) {
            record.setScore(0);
            return;
        }

        for (int i = 0; i < 10; i++) {
            if (accuracyRate.compareTo(new BigDecimal(80 - i)) <= 0 && accuracyRate.compareTo(new BigDecimal(79 - i)) > 0) {
                record.setScore(9 - i);
                break;
            }
        }
    }

    //获取销售完成配置得分
    private void getCompleteConfigScore(String ratingId, String userId, String userName, String orgId, List<ScoreInfoDO> recordList,
                                        Date createTime,List<String> errorInfo) throws Exception {
        BasisQueryVO baiscQueryVO = new BasisQueryVO();
        baiscQueryVO.setRatingId(ratingId);
        List<SalesCompleteConfigDO> completeConfigDOList = salesCompleteConfigDOMapper.selectByRatingId(baiscQueryVO);
        // 组装销售详情数据
        List<SalesCompleteDetailDO> salesCompleteDetailDOList = new ArrayList<>();
        getSalesCompleteDetailTypeDesAndSalesTargetAmount(userId, userName, createTime, completeConfigDOList, salesCompleteDetailDOList);
        getSalesCompleteActualSalesAmount(ratingId, orgId, completeConfigDOList, salesCompleteDetailDOList,errorInfo);
        if (salesCompleteDetailDOList.isEmpty()){
            return;
        }

        for (ScoreInfoDO scoreInfoDO : recordList) {
            String clientId = scoreInfoDO.getClientId();
            Integer salesCompletion = 0;
            for (SalesCompleteDetailDO salesCompleteDetailDO : salesCompleteDetailDOList) {
                String clientId1 = salesCompleteDetailDO.getClientId();
                if (clientId.equals(clientId1)) {
                    Integer score = salesCompleteDetailDO.getScore() == null ? 0 : salesCompleteDetailDO.getScore();
                    salesCompletion = salesCompletion + score;
                    salesCompleteDetailDO.setScoreInfoId(scoreInfoDO.getId());
                }
            }
            scoreInfoDO.setSalesCompletion(salesCompletion);
        }
        salesCompleteDetailDOMapper.batchInsert(salesCompleteDetailDOList);
    }

    private void getSalesCompleteActualSalesAmount(String ratingId, String orgId, List<SalesCompleteConfigDO> completeConfigDOList,
                                                   List<SalesCompleteDetailDO> salesCompleteDetailDOList,List<String> errorInfo) throws Exception {
        List<Long> completeConfigClient = new ArrayList<>();
        completeConfigDOList.forEach(x -> completeConfigClient.add(Long.valueOf(x.getClientId())));
        //获取所有代理商实际销售金额
        RatingConfigTimeDO ratingConfigTimeDO = ratingConfigTimeDOMapper.selectByRatingIdType(ratingId, RatingConfigTimeEnum.SalesCompletionConfig.getCode());
        if (null == ratingConfigTimeDO) {
            errorInfo.add("销售完成情况配置时间未设定");
            return;
        }
        if (completeConfigClient.isEmpty()){
            errorInfo.add("销售完成情况配置客户未设定");
            return;
        }

        List<SalesCompleteDetailDO> clientSalesAmount = salesCompleteDetailDOMapper.getClientSalesAmount(completeConfigClient
                , orgId, ratingConfigTimeDO.getStartTime(), ratingConfigTimeDO.getEndTime());
        for (SalesCompleteDetailDO salesCompleteDetailDO : salesCompleteDetailDOList) {
            String clientId = salesCompleteDetailDO.getClientId();
            Integer salesType = salesCompleteDetailDO.getSalesType();
            salesCompleteDetailDO.setScore(4);//等分默认为0
            salesCompleteDetailDO.setActualSalesAmount(BigDecimal.ZERO);//实际销售金额默认为0
            salesCompleteDetailDO.setCompleteRate(0 + "%");//完成率默认0

            getSalesCompleteDetailActualAmountAndScore(clientSalesAmount, salesCompleteDetailDO, clientId, salesType);
        }
    }

    private void getSalesCompleteDetailActualAmountAndScore(List<SalesCompleteDetailDO> clientSalesAmount, SalesCompleteDetailDO salesCompleteDetailDO, String clientId, Integer salesType) {
        if (null == clientSalesAmount || clientSalesAmount.isEmpty()) {
            return;
        }

        for (SalesCompleteDetailDO salesCompleteDetail : clientSalesAmount) {
            String clientId1 = salesCompleteDetail.getClientId();
            Integer salesType1 = salesCompleteDetail.getSalesType();
            if (clientId.equals(clientId1) && salesType.equals(salesType1)) {
                salesCompleteDetailDO.setActualSalesAmount(salesCompleteDetail.getActualSalesAmount() == null ? BigDecimal.ZERO : salesCompleteDetail.getActualSalesAmount());
                if (salesCompleteDetailDO.getSalesTargetAmount() == null || salesCompleteDetailDO.getSalesTargetAmount().compareTo(BigDecimal.ZERO) == 0) {
                    salesCompleteDetailDO.setCompleteRate(100 + "%");
                    salesCompleteDetailDO.setScore(10);
                    break;
                }

                BigDecimal completeRate = (salesCompleteDetailDO.getActualSalesAmount().divide(salesCompleteDetailDO.getSalesTargetAmount(), 4, BigDecimal.ROUND_HALF_DOWN))
                        .multiply(new BigDecimal(100)).setScale(2,BigDecimal.ROUND_HALF_DOWN);
                salesCompleteDetailDO.setCompleteRate(completeRate + "%");
                if (completeRate.compareTo(new BigDecimal(100)) > 0) {
                    salesCompleteDetailDO.setScore(10);
                }
                if (completeRate.compareTo(new BigDecimal(100)) <= 0 && completeRate.compareTo(new BigDecimal(90)) > 0) {
                    salesCompleteDetailDO.setScore(8);
                }
                if (completeRate.compareTo(new BigDecimal(90)) <= 0 && completeRate.compareTo(new BigDecimal(80)) > 0) {
                    salesCompleteDetailDO.setScore(6);
                }
                break;
            }
        }
    }

    private void getSalesCompleteDetailTypeDesAndSalesTargetAmount(String userId, String userName, Date createTime, List<SalesCompleteConfigDO> completeConfigDOList, List<SalesCompleteDetailDO> salesCompleteDetailDOList) {
        for (SalesCompleteConfigDO salesCompleteConfigDO : completeConfigDOList) {
            for (int i = 1; i < 8; i++) {
                SalesCompleteDetailDO salesCompleteDetailDO = new SalesCompleteDetailDO();
                salesCompleteDetailDO.setClientId(salesCompleteConfigDO.getClientId());
                salesCompleteDetailDO.setCreateTime(createTime);
                salesCompleteDetailDO.setCreatorId(userId);
                salesCompleteDetailDO.setCreatorName(userName);
                salesCompleteDetailDO.setId(genClient.newGuidText().getValue());
                if (i == SalesCompleteDetailEnum.OilProductSalesCompletionRate.getCode()) {
                    salesCompleteDetailDO.setSalesType(SalesCompleteDetailEnum.OilProductSalesCompletionRate.getCode());
                    salesCompleteDetailDO.setSalesDes(SalesCompleteDetailEnum.OilProductSalesCompletionRate.getDesc());
                    salesCompleteDetailDO.setSalesTargetAmount(salesCompleteConfigDO.getOilTarget());
                }

                if (i == SalesCompleteDetailEnum.FilterSalesCompletionRate.getCode()) {
                    salesCompleteDetailDO.setSalesType(SalesCompleteDetailEnum.FilterSalesCompletionRate.getCode());
                    salesCompleteDetailDO.setSalesDes(SalesCompleteDetailEnum.FilterSalesCompletionRate.getDesc());
                    salesCompleteDetailDO.setSalesTargetAmount(salesCompleteConfigDO.getFilterTarget());
                }

                if (i == SalesCompleteDetailEnum.BreakerSalesCompletionRate.getCode()) {
                    salesCompleteDetailDO.setSalesType(SalesCompleteDetailEnum.BreakerSalesCompletionRate.getCode());
                    salesCompleteDetailDO.setSalesDes(SalesCompleteDetailEnum.BreakerSalesCompletionRate.getDesc());
                    salesCompleteDetailDO.setSalesTargetAmount(salesCompleteConfigDO.getBrokenHammerTarget());
                }

                if (i == SalesCompleteDetailEnum.ToothSalesCompletionRate.getCode()) {
                    salesCompleteDetailDO.setSalesType(SalesCompleteDetailEnum.ToothSalesCompletionRate.getCode());
                    salesCompleteDetailDO.setSalesDes(SalesCompleteDetailEnum.ToothSalesCompletionRate.getDesc());
                    salesCompleteDetailDO.setSalesTargetAmount(salesCompleteConfigDO.getToothTarget());
                }

                if (i == SalesCompleteDetailEnum.FourRoundsOfSalesCompletionRate.getCode()) {
                    salesCompleteDetailDO.setSalesType(SalesCompleteDetailEnum.FourRoundsOfSalesCompletionRate.getCode());
                    salesCompleteDetailDO.setSalesDes(SalesCompleteDetailEnum.FourRoundsOfSalesCompletionRate.getDesc());
                    salesCompleteDetailDO.setSalesTargetAmount(salesCompleteConfigDO.getFourRoundsTarget());
                }

                if (i == SalesCompleteDetailEnum.HydraulicPartsSalesCompletionRate.getCode()) {
                    salesCompleteDetailDO.setSalesType(SalesCompleteDetailEnum.HydraulicPartsSalesCompletionRate.getCode());
                    salesCompleteDetailDO.setSalesDes(SalesCompleteDetailEnum.HydraulicPartsSalesCompletionRate.getDesc());
                    salesCompleteDetailDO.setSalesTargetAmount(salesCompleteConfigDO.getHydraulicTarget());
                }

                if (i == SalesCompleteDetailEnum.RubberPlasticPartsSalesCompletionRate.getCode()) {
                    salesCompleteDetailDO.setSalesType(SalesCompleteDetailEnum.RubberPlasticPartsSalesCompletionRate.getCode());
                    salesCompleteDetailDO.setSalesDes(SalesCompleteDetailEnum.RubberPlasticPartsSalesCompletionRate.getDesc());
                    salesCompleteDetailDO.setSalesTargetAmount(salesCompleteConfigDO.getRubberPartsTarget());
                }
                salesCompleteDetailDOList.add(salesCompleteDetailDO);
            }

        }
    }

    //获取评分列表
    public PageCommonVO list(SearchCommonVO<BasisQueryVO> condition) {
        String sort = condition.getSort();
        if (StringUtils.isBlank(sort)) {
            PageHelperPlus.orderBy("create_time,id desc");
        } else {
            PageHelperPlus.orderBy(sort);
        }
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        List<ScoreInfoDO> doList = scoreInfoDOMapper.selectByRatingId(condition.getFilters());
        List<ScoreInfoVO> voList = new ArrayList<>();
        for (ScoreInfoDO scoreInfoDO : doList) {
            ScoreInfoVO scoreInfoVO = new ScoreInfoVO();
            BeanUtils.copyProperties(scoreInfoDO, scoreInfoVO);
            voList.add(scoreInfoVO);
        }
        PageCommonVO<ScoreInfoVO> result = new PageCommonVO<>();
        result.setPageInfo(new PageInfo<>(doList));
        result.setPageInfoList(voList);
        return result;
    }

    public ErrorCode generateRanking(String ratingId) {
        BasisQueryVO basisQueryVO = new BasisQueryVO();
        basisQueryVO.setRatingId(ratingId);
        PageHelperPlus.orderBy("TOTAL_SCORE desc");
        List<ScoreInfoDO> doList = scoreInfoDOMapper.selectByRatingId(basisQueryVO);
        if (doList.isEmpty()) {
            return ErrorCode.RankingInfoNotExist;
        }
        List<MarketDealerRatingDO> dealerRatingDOList = marketDealerRatingMapper.selectByRatingId(ratingId);
        List<ScoreInfoDO> updateList = new ArrayList<>();
        int index = 0;
        for (int i = 0; i < doList.size(); i++) {
            ScoreInfoDO updateScoreInfoDO = new ScoreInfoDO();
            ScoreInfoDO scoreInfoDO = doList.get(i);
            if (i == 0 || scoreInfoDO.getTotalScore() < doList.get(i - 1).getTotalScore()) {
                index++;
            }
            updateScoreInfoDO.setRanking(index);
            updateScoreInfoDO.setId(scoreInfoDO.getId());
            updateScoreInfoDO.setClientId(scoreInfoDO.getClientId());
            updateList.add(updateScoreInfoDO);
        }
        getGrade(dealerRatingDOList, updateList);
        scoreInfoDOMapper.batchUpdate(updateList);
        return ErrorCode.Success;
    }

    private void getGrade(List<MarketDealerRatingDO> dealerRatingDOList, List<ScoreInfoDO> updateList) {
        if (dealerRatingDOList.isEmpty()) {
            return;
        }
        for (MarketDealerRatingDO marketDealerRatingDO : dealerRatingDOList) {
            Integer startRanking = marketDealerRatingDO.getStartRanking();
            Integer endRanking = marketDealerRatingDO.getEndRanking();
            String mainId = marketDealerRatingDO.getId();
            if (startRanking == null || endRanking == null) {
                continue;
            }
            String grad = marketDealerRatingDO.getGrad();
            for (ScoreInfoDO scoreInfoDO : updateList) {
                Integer ranking = scoreInfoDO.getRanking();
                if (ranking >= startRanking && ranking <= endRanking) {
                    scoreInfoDO.setGrade(grad);
                    String clientId = scoreInfoDO.getClientId();
                    CompanyDealerDO item = companyDealerMapper.item(Long.valueOf(clientId));
                    List<MarketingActivityVO> rule = ruleStrategyRelationDOMapper.selectByMainId(mainId);
                    if (rule.isEmpty()) {
                        continue;
                    }
                    for (MarketingActivityVO marketingActivityVO : rule) {
                        int count = marketDealerRatingDetailMapper.checkCount(mainId, item.getDealerOrgId(), marketingActivityVO.getId());
                        if (count > 0) {
                            continue;
                        }
                        MarketDealerRatingDetailDO marketDealerRatingDetailDO = new MarketDealerRatingDetailDO();
                        marketDealerRatingDetailDO.setMainId(mainId);
                        marketDealerRatingDetailDO.setDealerOrgName(item.getCompanyName());
                        marketDealerRatingDetailDO.setDealerOrgId(item.getDealerOrgId());
                        marketDealerRatingDetailDO.setActivityName(marketingActivityVO.getName());
                        marketDealerRatingDetailDO.setActivityId(marketingActivityVO.getId());
                        marketDealerRatingDetailDO.setCreateDate(new Date());
                        marketDealerRatingDetailDO.setEffectiveDate(marketDealerRatingDO.getEffectiveDate());
                        marketDealerRatingDetailDO.setFailureDate(marketDealerRatingDO.getFailureDate());
                        marketDealerRatingDetailDO.setId(genClient.newGuidText().getValue());
                        marketDealerRatingDetailDO.setUpdateDate(new Date());
                        marketDealerRatingDetailMapper.insertSelective(marketDealerRatingDetailDO);
                    }
                }
            }
        }
    }

    public void exportAll(BasisQueryVO condition) throws Exception {
        //PageHelperPlus.startPage(0, 0, "id desc");
        List<ScoreInfoDO> doList = scoreInfoDOMapper.selectByRatingId(condition);
        invokeExport(doList);
    }

    private void invokeExport(List<ScoreInfoDO> voList) throws Exception {
        String title = "评分数据导出";
        String[] rowsName = new String[]{"序号", "客户", "销售完成情况", "月度计划准确性", "订单管理规范性", "应收账款逾期",
                "总体销售完成率", "库存管理及业务规范性加减分", "总得分", "排名", "等级"};
        List<Object[]> dataList = new ArrayList<>();
        Object[] objs;
        for (int i = 0; i < voList.size(); i++) {
            ScoreInfoDO scoreInfoDO = voList.get(i);
            objs = new Object[rowsName.length];
            objs[0] = i + 1;
            objs[1] = scoreInfoDO.getClientName();
            objs[2] = scoreInfoDO.getSalesCompletion();
            objs[3] = scoreInfoDO.getMonthPlanAccuracy();
            objs[4] = scoreInfoDO.getOrderManagerNormative();
            objs[5] = scoreInfoDO.getAccountsOverdue();
            objs[6] = scoreInfoDO.getSalesCompletionRate();
            objs[7] = scoreInfoDO.getInventoryBusiness();
            objs[8] = scoreInfoDO.getTotalScore();
            objs[9] = scoreInfoDO.getRanking();
            objs[10] = scoreInfoDO.getGrade();
            dataList.add(objs);

        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }
}
